﻿using System;
using System.Reflection;
using Pfz.Extensions;
using System.IO;

namespace Pfz.Serialization.BinaryBuiltIn
{
	/// <summary>
	/// Serializes an Assembly (as a reference).
	/// </summary>
	public sealed class AssemblySerializer:
		IItemSerializer
	{
		/// <summary>
		/// Gets the singleton instance.
		/// </summary>
		public static readonly AssemblySerializer Instance = new AssemblySerializer();

		private AssemblySerializer()
		{
		}

		/// <summary>
		/// Serializes the assembly full name.
		/// </summary>
		public void Serialize(ConfigurableSerializerBase serializer, Assembly assembly)
		{
			string fullName = assembly.FullName;
			serializer.Stream.WriteString(fullName);
		}

		/// <summary>
		/// Receives the assembly name, loads it and returns it.
		/// </summary>
		public Assembly Deserialize(ConfigurableSerializerBase deserializer)
		{
			Assembly result;

			string assemblyName = deserializer.Stream.ReadString();
			try
			{
				result = Assembly.Load(assemblyName);
			}
			catch
			{
				int index = assemblyName.IndexOf(", PublicKeyToken=");
				if (index <= 0)
					throw;

				assemblyName = assemblyName.Substring(0, index);
				result = Assembly.Load(assemblyName);
			}

			return result;
		}

		private static readonly Type _forType = typeof(AssemblySerializer).Assembly.GetType();
		Type IItemSerializer.ForType
		{
			get
			{
				return _forType;
			}
		}

		void IItemSerializer.Serialize(ConfigurableSerializerBase serializer, object item)
		{
			Assembly assembly = (Assembly)item;
			Serialize(serializer, assembly);
		}
		object IItemSerializer.Deserialize(ConfigurableSerializerBase deserializer)
		{
			return Deserialize(deserializer);
		}
	}
}
